<template>
  <div class="csv-to-json-tool">
    <div class="tool-header">
      <h1>CSV转JSON</h1>
      <p>将CSV文件转换为JSON格式</p>
    </div>

    <div class="tool-container">
      <el-row :gutter="20">
        <!-- 转换主体 -->
        <el-col :span="16">
          <div class="converter-section">
            <!-- CSV输入 -->
            <div class="csv-input">
              <h3>CSV数据输入</h3>
              <div class="input-actions">
                <el-button @click="pasteCSV" size="small">
                  <el-icon><DocumentCopy /></el-icon>
                  粘贴CSV
                </el-button>
                <el-button @click="clearCSV" size="small">
                  清空
                </el-button>
                <el-button @click="loadSample" size="small">
                  加载示例
                </el-button>
                <el-button @click="uploadFile" size="small">
                  <el-icon><Upload /></el-icon>
                  上传文件
                </el-button>
              </div>
              <el-input
                v-model="inputCSV"
                type="textarea"
                :rows="10"
                placeholder="请输入CSV数据..."
                @input="convertCSV"
                class="csv-textarea"
              />
            </div>
            
            <!-- 转换选项 -->
            <div class="conversion-options">
              <h3>转换选项</h3>
              <div class="options-grid">
                <div class="option-group">
                  <label>分隔符：</label>
                  <el-select v-model="conversionOptions.delimiter" @change="convertCSV" size="small">
                    <el-option label="逗号 (,)" value="," />
                    <el-option label="分号 (;)" value=";" />
                    <el-option label="制表符" value="\t" />
                    <el-option label="竖线 (|)" value="|" />
                    <el-option label="自定义" value="custom" />
                  </el-select>
                </div>
                <div class="option-group" v-if="conversionOptions.delimiter === 'custom'">
                  <label>自定义分隔符：</label>
                  <el-input v-model="customDelimiter" @input="convertCSV" size="small" />
                </div>
                <div class="option-group">
                  <label>引号字符：</label>
                    <el-select v-model="conversionOptions.quote" @change="convertCSV" size="small">
                      <el-option label="双引号" value='"' />
                      <el-option label="单引号" value="'" />
                      <el-option label="无引号" value="" />
                    </el-select>
                </div>
                <div class="option-group">
                  <label>首行作为标题：</label>
                  <el-switch v-model="conversionOptions.header" @change="convertCSV" size="small" />
                </div>
                <div class="option-group">
                  <label>JSON格式：</label>
                  <el-select v-model="conversionOptions.jsonFormat" @change="convertCSV" size="small">
                    <el-option label="对象数组" value="array" />
                    <el-option label="键值对" value="object" />
                  </el-select>
                </div>
                <div class="option-group">
                  <label>美化输出：</label>
                  <el-switch v-model="conversionOptions.pretty" @change="convertCSV" size="small" />
                </div>
              </div>
            </div>
            
            <!-- 转换按钮 -->
            <div class="conversion-actions">
              <el-button @click="convertCSV" type="primary" size="large" :loading="isConverting" :disabled="!inputCSV.trim()">
                <el-icon><Sort /></el-icon>
                转换CSV
              </el-button>
              <el-button @click="clearAll" size="large">
                清空全部
              </el-button>
              <el-button @click="copyResult" size="large" :disabled="!convertedJSON">
                <el-icon><DocumentCopy /></el-icon>
                复制结果
              </el-button>
              <el-button @click="downloadResult" size="large" :disabled="!convertedJSON">
                <el-icon><Download /></el-icon>
                下载JSON
              </el-button>
            </div>
            
            <!-- 转换结果 -->
            <div class="conversion-result" v-if="convertedJSON">
              <h3>转换结果</h3>
              <div class="result-info">
                <div class="info-item">
                  <span class="info-label">CSV行数：</span>
                  <span class="info-value">{{ csvRows }}</span>
                </div>
                <div class="info-item">
                  <span class="info-label">JSON对象数：</span>
                  <span class="info-value">{{ jsonObjects }}</span>
                </div>
                <div class="info-item">
                  <span class="info-label">字段数量：</span>
                  <span class="info-value">{{ fieldCount }}</span>
                </div>
                <div class="info-item">
                  <span class="info-label">文件大小：</span>
                  <span class="info-value">{{ fileSize }}</span>
                </div>
              </div>
              <el-input
                v-model="convertedJSON"
                type="textarea"
                :rows="12"
                readonly
                class="json-textarea"
              />
            </div>
            
            <!-- 预览表格 -->
            <div class="preview-table" v-if="previewData.length > 0">
              <h3>数据预览</h3>
              <div class="table-container">
                <el-table :data="previewData" border stripe max-height="300">
                  <el-table-column 
                    v-for="(header, index) in tableHeaders" 
                    :key="index"
                    :prop="`col${index}`"
                    :label="header"
                    show-overflow-tooltip
                  />
                </el-table>
              </div>
            </div>
            
            <!-- 转换历史 -->
            <div class="conversion-history">
              <h3>转换历史</h3>
              <div class="history-list">
                <div 
                  v-for="(item, index) in conversionHistory" 
                  :key="index"
                  class="history-item"
                  @click="loadFromHistory(item)"
                >
                  <div class="history-info">
                    <span class="history-rows">{{ item.rows }} 行</span>
                    <span class="history-objects">{{ item.objects }} 对象</span>
                    <span class="history-time">{{ item.time }}</span>
                  </div>
                </div>
                <div v-if="conversionHistory.length === 0" class="empty-history">
                  暂无转换历史
                </div>
              </div>
            </div>
          </div>
        </el-col>

        <!-- 工具和说明 -->
        <el-col :span="8">
          <div class="tools-section">
            <div class="section-header">
              <h3>CSV示例</h3>
            </div>
            
            <div class="csv-samples">
              <div 
                v-for="sample in csvSamples" 
                :key="sample.name"
                class="sample-item"
                @click="loadSampleCSV(sample)"
              >
                <div class="sample-name">{{ sample.name }}</div>
                <div class="sample-description">{{ sample.description }}</div>
              </div>
            </div>
          </div>
          
          <div class="help-section">
            <el-card>
              <template #header>
                <div class="card-header">
                  <span>使用说明</span>
                </div>
              </template>
              
              <div class="help-content">
                <h4>支持的分隔符：</h4>
                <ul>
                  <li><strong>逗号：</strong> 标准CSV格式</li>
                  <li><strong>分号：</strong> 欧洲地区常用</li>
                  <li><strong>制表符：</strong> TSV格式</li>
                  <li><strong>竖线：</strong> 管道分隔</li>
                  <li><strong>自定义：</strong> 任意字符</li>
                </ul>
                
                <h4>JSON格式：</h4>
                <ul>
                  <li><strong>对象数组：</strong> [{}, {}, {}]</li>
                  <li><strong>键值对：</strong> {"key": "value"}</li>
                </ul>
                
                <h4>注意事项：</h4>
                <div class="warning">
                  <p>⚠️ 确保CSV格式正确</p>
                  <p>⚠️ 大型文件可能影响性能</p>
                  <p>⚠️ 特殊字符需要正确转义</p>
                </div>
              </div>
            </el-card>
          </div>
        </el-col>
      </el-row>
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { DocumentCopy, Upload, Sort, Download } from '@element-plus/icons-vue'

const inputCSV = ref('')
const convertedJSON = ref('')
const isConverting = ref(false)
const customDelimiter = ref('')
const previewData = ref([])
const tableHeaders = ref([])
const conversionHistory = ref([])

const conversionOptions = ref({
  delimiter: ',',
  quote: '"',
  header: true,
  jsonFormat: 'array',
  pretty: true
})

const csvSamples = [
  {
    name: '简单数据',
    description: '基本的CSV数据',
    csv: 'name,age,city\nJohn,30,New York\nJane,25,Los Angeles\nBob,35,Chicago'
  },
  {
    name: '带引号数据',
    description: '包含引号的数据',
    csv: '"姓名","年龄","城市"\n"张三","30","北京"\n"李四","25","上海"\n"王五","35","广州"'
  },
  {
    name: '分号分隔',
    description: '使用分号分隔',
    csv: 'name;age;city\nJohn;30;New York\nJane;25;Los Angeles\nBob;35;Chicago'
  },
  {
    name: '无标题行',
    description: '没有标题行的数据',
    csv: 'John,30,New York\nJane,25,Los Angeles\nBob,35,Chicago'
  }
]

const csvRows = computed(() => {
  return inputCSV.value ? inputCSV.value.split('\n').filter(line => line.trim()).length : 0
})

const jsonObjects = computed(() => {
  if (!convertedJSON.value) return 0
  try {
    const parsed = JSON.parse(convertedJSON.value)
    return Array.isArray(parsed) ? parsed.length : 1
  } catch {
    return 0
  }
})

const fieldCount = computed(() => {
  return tableHeaders.value.length
})

const fileSize = computed(() => {
  if (!convertedJSON.value) return '0 B'
  const bytes = new Blob([convertedJSON.value]).size
  if (bytes < 1024) return `${bytes} B`
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`
})

const pasteCSV = async () => {
  try {
    const text = await navigator.clipboard.readText()
    inputCSV.value = text
    convertCSV()
    ElMessage.success('CSV已粘贴')
  } catch (error) {
    ElMessage.error('无法访问剪贴板')
  }
}

const clearCSV = () => {
  inputCSV.value = ''
  convertedJSON.value = ''
  previewData.value = []
  tableHeaders.value = []
  ElMessage.info('CSV已清空')
}

const loadSample = () => {
  inputCSV.value = csvSamples[0].csv
  convertCSV()
  ElMessage.success('示例CSV已加载')
}

const loadSampleCSV = (sample) => {
  inputCSV.value = sample.csv
  convertCSV()
  ElMessage.success(`已加载：${sample.name}`)
}

const uploadFile = () => {
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = '.csv,.txt'
  input.onchange = (e) => {
    const file = e.target.files[0]
    if (file) {
      const reader = new FileReader()
      reader.onload = (e) => {
        inputCSV.value = e.target.result
        convertCSV()
        ElMessage.success('文件已上传')
      }
      reader.readAsText(file)
    }
  }
  input.click()
}

const clearAll = () => {
  inputCSV.value = ''
  convertedJSON.value = ''
  previewData.value = []
  tableHeaders.value = []
  ElMessage.info('已清空全部内容')
}

const convertCSV = async () => {
  if (!inputCSV.value.trim()) {
    convertedJSON.value = ''
    previewData.value = []
    tableHeaders.value = []
    return
  }
  
  isConverting.value = true
  
  try {
    // 模拟转换过程
    await new Promise(resolve => setTimeout(resolve, 500))
    
    const delimiter = conversionOptions.value.delimiter === 'custom' ? customDelimiter.value : conversionOptions.value.delimiter
    const lines = inputCSV.value.split('\n').filter(line => line.trim())
    
    if (lines.length === 0) {
      convertedJSON.value = ''
      return
    }
    
    let headers = []
    let dataRows = lines
    
    if (conversionOptions.value.header) {
      headers = parseCSVLine(lines[0], delimiter)
      dataRows = lines.slice(1)
    } else {
      // 如果没有标题，使用列索引作为标题
      const firstRow = parseCSVLine(lines[0], delimiter)
      headers = firstRow.map((_, index) => `column${index + 1}`)
    }
    
    // 解析数据行
    const jsonData = dataRows.map(line => {
      const values = parseCSVLine(line, delimiter)
      const obj = {}
      headers.forEach((header, index) => {
        obj[header] = values[index] || ''
      })
      return obj
    })
    
    // 生成JSON
    let jsonString
    if (conversionOptions.value.jsonFormat === 'array') {
      jsonString = JSON.stringify(jsonData, null, conversionOptions.value.pretty ? 2 : 0)
    } else {
      // 键值对格式
      const keyValueObj = {}
      jsonData.forEach((item, index) => {
        keyValueObj[`row${index + 1}`] = item
      })
      jsonString = JSON.stringify(keyValueObj, null, conversionOptions.value.pretty ? 2 : 0)
    }
    
    convertedJSON.value = jsonString
    
    // 更新预览数据
    updatePreviewData(headers, jsonData)
    
    // 添加到历史
    addToHistory()
    
    ElMessage.success('CSV转换完成')
    
  } catch (error) {
    ElMessage.error('转换失败：' + error.message)
  } finally {
    isConverting.value = false
  }
}

const parseCSVLine = (line, delimiter) => {
  const values = []
  let current = ''
  let inQuotes = false
  let quoteChar = conversionOptions.value.quote
  
  for (let i = 0; i < line.length; i++) {
    const char = line[i]
    
    if (char === quoteChar && !inQuotes) {
      inQuotes = true
    } else if (char === quoteChar && inQuotes) {
      inQuotes = false
    } else if (char === delimiter && !inQuotes) {
      values.push(current.trim())
      current = ''
    } else {
      current += char
    }
  }
  
  values.push(current.trim())
  return values
}

const updatePreviewData = (headers, data) => {
  tableHeaders.value = headers
  previewData.value = data.slice(0, 10).map(item => {
    const row = {}
    headers.forEach((header, index) => {
      row[`col${index}`] = item[header]
    })
    return row
  })
}

const copyResult = async () => {
  try {
    await navigator.clipboard.writeText(convertedJSON.value)
    ElMessage.success('结果已复制到剪贴板')
  } catch (error) {
    ElMessage.error('复制失败')
  }
}

const downloadResult = () => {
  const filename = 'converted.json'
  
  const blob = new Blob([convertedJSON.value], { type: 'application/json' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = filename
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  URL.revokeObjectURL(url)
  
  ElMessage.success('JSON文件已下载')
}

const addToHistory = () => {
  const historyItem = {
    rows: csvRows.value,
    objects: jsonObjects.value,
    time: new Date().toLocaleString('zh-CN')
  }
  
  conversionHistory.value.unshift(historyItem)
  
  // 限制历史记录数量
  if (conversionHistory.value.length > 20) {
    conversionHistory.value = conversionHistory.value.slice(0, 20)
  }
}

const loadFromHistory = (item) => {
  ElMessage.success(`已加载：${item.rows} 行转换历史`)
}
</script>

<style scoped>
.csv-to-json-tool {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

.tool-header {
  text-align: center;
  margin-bottom: 40px;
}

.tool-header h1 {
  font-size: 2.5rem;
  color: #333;
  margin-bottom: 10px;
}

.tool-header p {
  color: #666;
  font-size: 1.1rem;
}

.tool-container {
  margin-bottom: 40px;
}

.converter-section,
.tools-section {
  background: white;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
  border: 1px solid #f0f0f0;
  height: 100%;
}

.csv-input,
.conversion-options,
.conversion-actions,
.conversion-result,
.preview-table,
.conversion-history {
  margin-bottom: 30px;
}

.csv-input h3,
.conversion-options h3,
.conversion-result h3,
.preview-table h3,
.conversion-history h3 {
  color: #333;
  margin-bottom: 20px;
  font-size: 1.3rem;
}

.input-actions {
  display: flex;
  gap: 10px;
  margin-bottom: 15px;
}

.csv-textarea,
.json-textarea {
  font-family: 'Courier New', monospace;
  font-size: 14px;
  line-height: 1.5;
}

.conversion-options {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 20px;
  border: 1px solid #e9ecef;
}

.options-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 15px;
}

.option-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.option-group label {
  font-weight: 500;
  color: #666;
}

.conversion-actions {
  display: flex;
  gap: 15px;
  flex-wrap: wrap;
}

.result-info {
  display: flex;
  gap: 20px;
  margin-bottom: 15px;
  padding: 15px;
  background: #f8f9fa;
  border-radius: 8px;
  border: 1px solid #e9ecef;
}

.info-item {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.info-label {
  font-size: 0.9rem;
  color: #666;
  margin-bottom: 5px;
}

.info-value {
  font-size: 1.1rem;
  font-weight: bold;
  color: #333;
}

.preview-table {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 20px;
  border: 1px solid #e9ecef;
}

.table-container {
  max-height: 300px;
  overflow-y: auto;
}

.history-list {
  max-height: 300px;
  overflow-y: auto;
}

.history-item {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 15px;
  margin-bottom: 10px;
  cursor: pointer;
  transition: all 0.2s ease;
  border: 1px solid #e9ecef;
}

.history-item:hover {
  background: #e9ecef;
  transform: translateY(-1px);
}

.history-info {
  display: flex;
  gap: 15px;
  font-size: 0.9rem;
  color: #666;
}

.history-rows {
  color: #667eea;
  font-weight: 500;
}

.history-objects {
  color: #28a745;
  font-weight: 500;
}

.history-time {
  color: #999;
}

.empty-history {
  text-align: center;
  color: #999;
  padding: 40px 0;
  font-style: italic;
}

.section-header {
  margin-bottom: 20px;
}

.section-header h3 {
  color: #333;
  margin: 0;
  font-size: 1.3rem;
}

.csv-samples {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.sample-item {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 15px;
  cursor: pointer;
  transition: all 0.2s ease;
  border: 1px solid #e9ecef;
}

.sample-item:hover {
  background: #e9ecef;
  transform: translateY(-2px);
}

.sample-name {
  font-size: 1rem;
  font-weight: bold;
  color: #333;
  margin-bottom: 5px;
}

.sample-description {
  font-size: 0.9rem;
  color: #666;
}

.help-section {
  margin-top: 20px;
}

.card-header {
  font-weight: bold;
  color: #333;
}

.help-content h4 {
  color: #333;
  margin: 20px 0 10px 0;
  font-size: 1.1rem;
}

.help-content ul {
  color: #666;
  padding-left: 20px;
  margin-bottom: 15px;
}

.help-content li {
  margin-bottom: 5px;
}

.warning {
  background: #fff3cd;
  padding: 15px;
  border-radius: 8px;
  border-left: 4px solid #ffc107;
  margin: 15px 0;
}

.warning p {
  margin: 5px 0;
  color: #856404;
}

@media (max-width: 768px) {
  .tool-header h1 {
    font-size: 2rem;
  }
  
  .options-grid {
    grid-template-columns: 1fr;
  }
  
  .conversion-actions {
    flex-direction: column;
  }
  
  .result-info {
    flex-direction: column;
    gap: 10px;
  }
  
  .history-info {
    flex-direction: column;
    gap: 5px;
  }
}
</style>
